/*=============================================================================
*
*   Copyright (C) 2020 All rights reserved.
*
*   Filename:		test_gauss.cpp
*
*   Author: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Date: 2020-02-29 01:46
*
*   Last Editors: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Last modified:	2020-08-04 01:47
*
*   Description:
*
=============================================================================*/
#define BOOST_AUTO_TEST_MAIN

#include "../include/biot.hpp"
#include "../include/fem.hpp"
#include "../include/implicit_solver.hpp"
#include "../include/incremental_load.hpp"
#include "../include/model/model.hpp"
#include "../include/solid.hpp"
#include "../include/static_equation.hpp"
#include <boost/test/included/unit_test.hpp>

using namespace geoxfem::geometry;
using namespace geoxfem::model;
using namespace geoxfem::arithmetic;
using namespace geoxfem;

LOGGING_REGISTER()

struct func1 {
  template <typename T, typename P>
  _real operator()(const T&, const P&) const {
    return 0.5;
  }
};
struct func2 {
  template <typename T, typename P>
  _real operator()(const T&, const P& gp) const {
    return gp.getCoord(0) - 1;
  }
};
struct func3 {
  /* template <typename T> */
  /* _real operator()(const T& v) const { */
  /*   return v.getHeadPoint().getCoord(0) - 1; */
  /* } */
  template <typename T>
  _real operator()(const T* v) const {
    return v->getHeadPoint().getCoord(0) - 1;
  }
};

BOOST_AUTO_TEST_CASE(test_gauss) {
  using Shape = ShapeInterface<plane_stress, mpl1>;

  /*variables{{{*/
  geoxfem::log::log_init(geoxfem::log::severity_level::info);

  Point2D p1(1, 1), p2(4, 1), p3(4, 4), p4(1, 4), p5(1, -1), p6(-1, 1);
  Model<fem, solid, plane_stress, static_equation, implicit_solver,
        incremental_load, mpl1>
    model;

  model.register_type();

  p1.setIndex(1);
  model.append(p1);
  p2.setIndex(2);
  model.append(p2);
  p3.setIndex(3);
  model.append(p3);
  p4.setIndex(4);
  model.append(p4);
  p5.setIndex(5);
  model.append(p5);
  p6.setIndex(6);
  model.append(p6);

  Vector2R coord;
  coord << 3, 3;

  auto tri1  = Shape::getFactory().create("Triangle", {p1.shallowClone(),  //
                                                      p5.shallowClone(),  //
                                                      p6.shallowClone()});
  auto ptr1  = model.append(tri1, model.getMesh());
  auto quad1 = Shape::getFactory().create("Quadrangle", {p1.shallowClone(),  //
                                                         p2.shallowClone(),  //
                                                         p3.shallowClone(),  //
                                                         p4.shallowClone()});
  auto ptr2  = model.append(quad1, model.getMesh());
  for(auto& v : shapesIn(model, 0))
    set_nodal_dofs<model::biot>::apply(v->toVertex());
  auto dof_handler = model.getDofHandler();
  auto mesh        = model.getMesh();
  dof_handler->update(*mesh);

  BOOST_CHECK_CLOSE(algorithm::integral(*ptr1, func1()), 1, 1e-1);
  BOOST_CHECK_CLOSE(algorithm::integral(*ptr2, func2()), 13.5, 1e-1);
  BOOST_CHECK_CLOSE(algorithm::interpolate(*ptr1, coord, func3()), 2, 1e-1);
  BOOST_CHECK(dof_handler->getNEQ() == 18);
}
